﻿using FrameWork.Extensions;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Cors.Internal;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System;
using System.IO;
using System.Text;

namespace FrameWork
{
    public static class TimHttpContext
    {
        public static IServiceProvider ServiceProvider;
        public static IConfiguration Configuration;        
        public static void Init(IServiceCollection services, string cookieName, int timeout = 20)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            ServiceProvider = services.BuildServiceProvider();
            Configuration = ServiceProvider.GetRequiredService<IConfiguration>();         

          services.AddSession(options =>
            {
                options.Cookie.HttpOnly = true;
                options.Cookie.Name = cookieName;
                options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;

                if (timeout == 0) return;

                options.IdleTimeout = TimeSpan.FromMinutes(timeout);
            });

            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidAudience = Configuration["JwtSettings:Audience"],
                    ValidIssuer = Configuration["JwtSettings:Issuer"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtSettings:SecretKey"]))
                };
            });

            services.AddSwaggerGen(options =>
            {
                options.CustomSchemaIds(x => x.FullName);

                options.SwaggerDoc("v1", new OpenApiInfo
                {
                    Version = "v1",
                    Title = "API",
                    Description = "蓝华客服平台API"
                });

                options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization: \"Authorization: Bearer {token}\"",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                    Scheme = "Bearer"
                });

                var basePath = PlatformServices.Default.Application.ApplicationBasePath;
                options.IncludeXmlComments(Path.Combine(basePath, "lhservice.xml"));
                options.IncludeXmlComments(Path.Combine(basePath, "FrameWork.xml"));
                options.IncludeXmlComments(Path.Combine(basePath, "DBEntitie.xml"));
            });

            if (bool.TryParse(Configuration["AppSettings:redirect"], out var redirect) && redirect)
            {
                services.AddMvcCore(options =>
                {
                    options.Filters.Add(typeof(ActionRedirectAttribute));
                }).AddApiExplorer();
            }
            else
            {
                services.AddMvcCore().AddApiExplorer();
            }

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            services.AddCors(options =>
            {
                options.AddPolicy("AllowCors", builder =>
                {
                    builder.AllowAnyOrigin()
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials();
                });
            });
            services.Configure<MvcOptions>(options => options.Filters.Add(new CorsAuthorizationFilterFactory("AllowCors")));

        }
      
        public static HttpContext Context
        {
            get
            {
                try
                {
                    return ServiceProvider.GetRequiredService<IHttpContextAccessor>().HttpContext;
                }
                catch (Exception)
                {
                    throw new IException("Cookes跟踪失败");
                }
            }
        }
    }
}
